package org.cybzacg.convert.converters.gather;

import org.cybzacg.convert.annotation.Converter;
import org.cybzacg.convert.enums.ConversionError;
import org.cybzacg.convert.enums.ConversionPriority;
import org.cybzacg.convert.enums.ConversionType;
import org.cybzacg.convert.exception.ConversionException;
import lombok.extern.slf4j.Slf4j;

import java.util.*;
import java.util.concurrent.CopyOnWriteArrayList;

/**
 * List类型转换器
 * 支持各种List类型之间的转换
 *
 * @author cybzacg.blog
 * @version 4.0
 * @since 3.0
 */
@Slf4j
@Converter(name = "ListConverter", priority = ConversionPriority.MEDIUM, description = "List类型转换器，支持各种List类型之间的转换", enabled = true, version = "4.0", author = "cybzacg.blog", supportedTypes = {
        List.class }, tags = { "list", "collection", "conversion" })
public class ListConverter extends AbstractCollectionConverter<List<Object>> {

    // List类型实现类映射
    private static final Map<Class<?>, Class<?>> LIST_IMPLEMENTATIONS = new HashMap<>();

    static {
        LIST_IMPLEMENTATIONS.put(List.class, ArrayList.class);
        LIST_IMPLEMENTATIONS.put(AbstractList.class, ArrayList.class);
        LIST_IMPLEMENTATIONS.put(AbstractSequentialList.class, LinkedList.class);
    }

    public ListConverter() {
        super(List.class, ConversionPriority.MEDIUM);
    }

    @Override
    protected ConversionType getConversionType() {
        return ConversionType.LIST;
    }

    @Override
    @SuppressWarnings("unchecked")
    protected <T> List<Object> createEmptyCollection(Class<T> targetType) {
        try {
            // 如果是具体的List实现类，直接实例化
            if (List.class.isAssignableFrom(targetType) &&
                    !targetType.isInterface() &&
                    !java.lang.reflect.Modifier.isAbstract(targetType.getModifiers())) {
                return (List<Object>) targetType.getDeclaredConstructor().newInstance();
            }

            // 根据接口类型选择实现类
            Class<?> implementationClass = LIST_IMPLEMENTATIONS.get(targetType);
            if (implementationClass != null) {
                return (List<Object>) implementationClass.getDeclaredConstructor().newInstance();
            }

            // 根据目标类型特征选择合适的实现
            if (targetType.getName().contains("LinkedList")) {
                return new LinkedList<>();
            } else if (targetType.getName().contains("CopyOnWrite")) {
                return new CopyOnWriteArrayList<>();
            }

            // 默认使用ArrayList
            return new ArrayList<>();

        } catch (Exception e) {
            throw new ConversionException(ConversionError.CONVERSION_FAILED,
                    "无法创建List实例: " + targetType.getSimpleName(), e);
        }
    }

    @Override
    protected String getDefaultMapConversionMode() {
        return "entries"; // List默认转换Map的entries
    }

    @Override
    public String getName() {
        return "ListConverter";
    }

    // ========== 静态工具方法 ==========

    /**
     * 检查是否为List类型
     */
    public static boolean isListType(Class<?> clazz) {
        return List.class.isAssignableFrom(clazz);
    }

    /**
     * 创建ArrayList的便捷方法
     */
    public static ArrayList<Object> toArrayList(Object source) {
        ListConverter converter = new ListConverter();
        try {
            return (ArrayList<Object>) converter.convertToCollection(source, ArrayList.class, null);
        } catch (Exception e) {
            throw new ConversionException(ConversionError.CONVERSION_FAILED,
                    "转换为ArrayList失败: " + source, e);
        }
    }

    /**
     * 创建LinkedList的便捷方法
     */
    public static LinkedList<Object> toLinkedList(Object source) {
        ListConverter converter = new ListConverter();
        try {
            return (LinkedList<Object>) converter.convertToCollection(source, LinkedList.class, null);
        } catch (Exception e) {
            throw new ConversionException(ConversionError.CONVERSION_FAILED,
                    "转换为LinkedList失败: " + source, e);
        }
    }

    /**
     * 检查List是否为空或null
     */
    public static boolean isEmpty(List<?> list) {
        return list == null || list.isEmpty();
    }

    /**
     * 获取List的安全大小
     */
    public static int safeSize(List<?> list) {
        return list != null ? list.size() : 0;
    }
}
